package com.sg.common.login.service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang3.StringUtils;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.ProjectionList;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.springframework.stereotype.Component;

import com.alibaba.fastjson.JSONObject;
import com.sg.common.dao.BaseDao;
import com.sg.common.empty.json.Permission;
import com.sg.common.http.HttpHelper;
import com.sg.common.login.entity.Member;
import com.sg.common.login.entity.Org;
import com.sg.common.login.entity.OrgMember;
import com.sg.common.login.entity.Role;
import com.sg.common.login.entity.RoleMember;
import com.sg.common.login.entity.RoleOrg;
import com.sg.common.utils.CollUtil;
import com.sg.common.utils.Constant;

/**
 * 请假实体管理接口
 * 
 * @author HenryYan
 * @param <T>
 * @param <T>
 */
@Component
public class OrgMemberService extends BaseDao {

	public List<Org> findMyOrgs(Member member) {
		List<Org> res = new ArrayList<Org>();
		DetachedCriteria dc = DetachedCriteria.forClass(OrgMember.class);
		dc.add(Restrictions.eq("member", member)).add(
				Restrictions.eq("enable", "1"));
		List<OrgMember> ol = find(dc);
		for (OrgMember om : ol) {
			res.add(om.getOrg());
		}
		return res;
	}

	public List<Org> findMyOrgsIndirect(Member member) {
		List<Org> res = new ArrayList<Org>();
		DetachedCriteria dc = DetachedCriteria.forClass(OrgMember.class);
		dc.add(Restrictions.eq("member", member)).add(
				Restrictions.eq("enable", "1"));
		List<OrgMember> ol = find(dc);
		for (OrgMember om : ol) {
			Org org = om.getOrg();
			if (org != null) {
				pp(res, org);
			}
		}
		return res;
	}

	private void pp(List<Org> res, Org org) {
		res.add(org);
		if (org.getParent() != null) {
			DetachedCriteria dc = DetachedCriteria.forClass(Org.class);
			dc.add(Restrictions.eq("id", org.getParent().getId())).add(
					Restrictions.eq("delfg", "0"));
			Org parent = findBean(dc);
			if (parent != null) {
				pp(res, parent);
			}
		}
	}

	/**
	 * 未对重复的att做判断
	 * 
	 * @param service
	 * @param member
	 * @return
	 */
	public List<String> findMyOrgsAtts(Member member) {
		List<Org> myOrgs = findMyOrgs(member);
		List<String> atts = new ArrayList<String>();
		for (Org o : myOrgs) {
			if (StringUtils.isNotEmpty(o.getAtt1())) {
				atts.add(o.getAtt1());
			}
			if (StringUtils.isNotEmpty(o.getAtt2())) {
				atts.add(o.getAtt2());
			}
			if (StringUtils.isNotEmpty(o.getAtt3())) {
				atts.add(o.getAtt3());
			}
		}
		return atts;
	}

	/**
	 * 判断工号密码是否正确
	 * 
	 * @param request
	 * @return
	 */
	public Member confirmMember(String code, String psd) {
		DetachedCriteria dc;

		// 通过人员对应角色
		dc = DetachedCriteria.forClass(Member.class);
		dc.add(Restrictions.eq("loginId", code));
		Member m = findBean(dc);

		Map<String, String> mip = new HashMap<String, String>();

		mip.put("code", code);
		mip.put("psd", psd);

		JSONObject httpRes = HttpHelper.httpPost(Constant.get("checkpsd"), mip);
		if (httpRes != null
				&& StringUtils.equals(httpRes.getString("errmsg"), "ok"))
			return m;
		else {
			return null;
		}
	}

	public List<Role> findMyRoles(Member member) {
		DetachedCriteria dc;
		List<Role> myRoles = new ArrayList<Role>();

		// 通过人员对应角色
		dc = DetachedCriteria.forClass(RoleMember.class);
		dc.add(Restrictions.eq("member", member));
		dc.add(Restrictions.eq("enable", Constant.ENABLE_NOR));
		List<RoleMember> roleMembers = find(dc);
		for (RoleMember rm : roleMembers) {
			myRoles.add(rm.getRole());
		}
		// 通过我的组织的属性来对应角色
//		List<String> atts = findMyOrgsAtts(member);
//		if (CollUtil.isNotEmpty(atts)) {
//			dc = DetachedCriteria.forClass(RoleAtt.class);
//			dc.add(Restrictions.in("att", atts));
//			dc.add(Restrictions.eq("enable", Constant.ENABLE_NOR));
//			List<RoleAtt> roleAtts = find(dc);
//			for (RoleAtt r : roleAtts) {
//				myRoles.add(r.getRole());
//			}
//		}
		// 通过我的组织来找对应的角色 ROLEORG
		List<Org> myOrgs = new ArrayList<Org>();
		dc = DetachedCriteria.forClass(OrgMember.class);
		dc.add(Restrictions.eq("member", member));// 或者我的部门在org下面
		dc.add(Restrictions.eq("enable", Constant.ENABLE_NOR));
		List<OrgMember> oml = find(dc);
		for (OrgMember om : oml) {
			Org org = om.getOrg();
			myOrgs.add(org);
		}
		if (CollUtil.isNotEmpty(myOrgs)) {
			dc = DetachedCriteria.forClass(RoleOrg.class);
			dc.add(Restrictions.in("org", myOrgs));
			dc.add(Restrictions.eq("enable", Constant.ENABLE_NOR));
			List<RoleOrg> roleOrgs = find(dc);
			for (RoleOrg r : roleOrgs) {
				myRoles.add(r.getRole());
			}
		}
		return myRoles;
	}

	public List<Role> findMyRoles(HttpServletRequest request, Member member) {
		DetachedCriteria dc;
		List<Role> myRoles = new ArrayList<Role>();

		// 通过人员对应角色
		dc = DetachedCriteria.forClass(RoleMember.class);
		dc.add(Restrictions.eq("member", member));
		dc.add(Restrictions.eq("enable", Constant.ENABLE_NOR));
		List<RoleMember> roleMembers = find(dc);
		for (RoleMember rm : roleMembers) {
			myRoles.add(rm.getRole());
		}
		// 通过我的组织的属性来对应角色
//		List<String> atts = findMyOrgsAtts(member);
//		if (CollUtil.isNotEmpty(atts)) {
//			dc = DetachedCriteria.forClass(RoleAtt.class);
//			dc.add(Restrictions.in("att", atts));
//			dc.add(Restrictions.eq("enable", Constant.ENABLE_NOR));
//			List<RoleAtt> roleAtts = find(dc);
//			for (RoleAtt r : roleAtts) {
//				myRoles.add(r.getRole());
//			}
//		}
		// 通过我的组织来找对应的角色 ROLEORG
		List<Org> myOrgs = (List<Org>) request.getSession().getAttribute(
				Constant.SESSION_MYORGS_INDIRECT);
		if (CollUtil.isNotEmpty(myOrgs)) {
			dc = DetachedCriteria.forClass(RoleOrg.class);
			dc.add(Restrictions.in("org", myOrgs));
			dc.add(Restrictions.eq("enable", Constant.ENABLE_NOR));
			List<RoleOrg> roleOrgs = find(dc);
			for (RoleOrg r : roleOrgs) {
				myRoles.add(r.getRole());
			}
		}
		return myRoles;
	}
//
//	public List<Permission> findMyPermissions(List<Role> myRoles, String type) {
//		List<Permission> rpl = new ArrayList<Permission>();
//		if (CollUtil.isNotEmpty(myRoles)) {
//			DetachedCriteria dc = DetachedCriteria
//					.forClass(RolePermission.class);
//			dc.createAlias("permission", "p");
//			dc.add(Restrictions.in("role", myRoles)).add(
//					Restrictions.eq("p.enable", "1"));
//			if (StringUtils.isNotEmpty(type)) {
//				dc.add(Restrictions.eq("p.type", type));
//			}
//			ProjectionList projectionList = Projections.projectionList();
//			projectionList.add(Projections.property("permission"));
//			dc.setProjection(Projections.distinct(projectionList));// 防止多个角色下的功能重复。
//			rpl = find(dc);
//		}
//		return rpl;
//	}

//	public List<Permission> findMyPermissions(Member member, String type) {
//		List<Role> myRoles = findMyRoles(member);
//		List<Permission> rpl = new ArrayList<Permission>();
//		if (CollUtil.isNotEmpty(myRoles)) {
//			DetachedCriteria dc = DetachedCriteria
//					.forClass(RolePermission.class);
//			dc.createAlias("permission", "p");
//			dc.add(Restrictions.in("role", myRoles)).add(
//					Restrictions.eq("p.enable", "1"));
//			if (StringUtils.isNotEmpty(type)) {
//				dc.add(Restrictions.eq("p.type", type));
//			}
//			ProjectionList projectionList = Projections.projectionList();
//			projectionList.add(Projections.property("permission"));
//			dc.setProjection(Projections.distinct(projectionList));// 防止多个角色下的功能重复。
//			rpl = find(dc);
//		}
//		return rpl;
//	}
//
//	public List<Permission> findMyAddPermissionsWithFullD(List<Role> myRoles) {
//		List<Permission> rpl = new ArrayList<Permission>();
//		if (CollUtil.isNotEmpty(myRoles)) {
//			DetachedCriteria dc = DetachedCriteria
//					.forClass(RolePermission.class);
//			dc.createAlias("permission", "p");
//			dc.add(Restrictions.in("role", myRoles))
//					.add(Restrictions.eq("p.enable", "1"))
//					.add(Restrictions.eq("p.uri2", "add"))
//					// .add(Restrictions.isNotNull("p.fullDescr"))
//					.add(Restrictions.not(Restrictions.eqOrIsNull(
//							"p.fullDescr", "")));
//
//			ProjectionList projectionList = Projections.projectionList();
//			projectionList.add(Projections.property("permission"));
//			dc.setProjection(Projections.distinct(projectionList));// 防止多个角色下的功能重复。
//			rpl = find(dc);
//		}
//		return rpl;
//	}

	/**
	 * 办事员所管辖的组织
	 * 
	 * @param myOrgs
	 * @return
	 */
	public List<Org> bsyManageOrgs(List<Org> myOrgs) {
		List<Org> myManageOrgs = new ArrayList<Org>();
		for (Org o : myOrgs) {
			if (StringUtils.equals(o.getAtt1(), "1")
					&& StringUtils.equals(o.getOrge(), "1200")) {
				Org parent = o.getParent();
				if (parent != null) {
					findChild(myManageOrgs, parent);
				}

			}
		}
		return myManageOrgs;
	}

	private void findChild(List<Org> allOrgs, Org parent) {

		allOrgs.add(parent);
		List<Org> orgs = findByParent(parent);

		for (Object o : orgs) {

			findChild(allOrgs, (Org) o);
		}
	}

	private List<Org> findByParent(Org p) {
		DetachedCriteria dc = DetachedCriteria.forClass(Org.class);
		String pid = p.getId();
		if (!StringUtils.isNotEmpty(pid)) {
			dc.add(Restrictions.isNull("parent"));
		} else {
			dc.add(Restrictions.eq("parent", p));
		}
		dc.add(Restrictions.eq("delfg", "0"));
		List<Org> pl = find(dc);

		return pl;
	}

	public boolean memInOrg(String memberCode, String orgCode) {
		DetachedCriteria dc = DetachedCriteria.forClass(OrgMember.class);
		dc.createAlias("org", "org").createAlias("member", "mem")
				.add(Restrictions.eq("org.code", orgCode))
				.add(Restrictions.eq("mem.code", memberCode));
		List<Object> res = find(dc);
		return res != null && res.size() > 0;
	}

	/**
	 * 找到某人的内部组织
	 * 
	 * @param m
	 * @return
	 */
	public Org findMyOffiOrg(Member m) {
		Org res = null;
		String[] orges = { "1000", "1300" };
		DetachedCriteria dc = DetachedCriteria.forClass(OrgMember.class);
		dc.createAlias("org", "org");
		dc.add(Restrictions.eq("member", m))
				.add(Restrictions.in("org.orge", orges))
				.add(Restrictions.eq("delfg", "0"))
				.add(Restrictions.eq("enable", "1"));
		OrgMember om = findBean(dc);
		if (om != null) {
			res = om.getOrg();
		}
		return res;
	}

	/**
	 * 找到某组织平级的办事员
	 * 
	 * @param m
	 * @return
	 */
	public List<Member> findBsyByOrg(Org o) {
		List<Member> res = null;

		DetachedCriteria dc = DetachedCriteria.forClass(Org.class);
		//如果是3级（工班）则找车间办事员，其他找平级办事员
		dc.add(Restrictions.eq("parent", o))
		.add(Restrictions.eq("att1", "1"))
		// 1是办事员组 2是领导组 3是分管领导组
		.add(Restrictions.eq("orge", "1200")) 
		.add(Restrictions.eq("delfg", "0"))
		.add(Restrictions.eq("enable", "1"));
		Org bsyOrg = findBean(dc);
		if(bsyOrg==null)
		{
			dc = DetachedCriteria.forClass(Org.class);
			dc.add(Restrictions.eq("parent", o.getParent()))
			.add(Restrictions.eq("att1", "1"))
			// 1是办事员组 2是领导组 3是分管领导组
			.add(Restrictions.eq("orge", "1200")) 
			.add(Restrictions.eq("delfg", "0"))
			.add(Restrictions.eq("enable", "1"));
			bsyOrg = findBean(dc);	
		}
		if(bsyOrg==null)
		{
			dc = DetachedCriteria.forClass(Org.class);
			dc.add(Restrictions.eq("parent", o.getParent().getParent()))
					.add(Restrictions.eq("att1", "1"))
					// 1是办事员组 2是领导组 3是分管领导组
					.add(Restrictions.eq("orge", "1200"))
					.add(Restrictions.eq("delfg", "0"))
					.add(Restrictions.eq("enable", "1"));
			bsyOrg = findBean(dc);
		}
		
		if (bsyOrg != null) {
			res = findMemInOrg(bsyOrg.getCode());
		}
		return res;
	}

	/**
	 * 找到某人的固定层级的内部组织
	 * 
	 * @param m
	 * @return
	 */
	public Org findParentOrgByLeve(Org org, int leve) {
		Org res = null;
		int orgleve = Integer.valueOf(org.getOrglv());
		if (orgleve == leve) {
			res = org;
		} else {
			if (orgleve > leve)
				res = findParentOrgByLeve(org.getParent(), leve);
		}
		return res;
	}

	/**
	 * 找到组织内部人员
	 * 
	 * @param orgCode
	 * @return
	 */
	public List<Member> findMemInOrg(String orgCode) {
		List<Member> res = new ArrayList<Member>();
		DetachedCriteria dc = DetachedCriteria.forClass(OrgMember.class);
		dc.createAlias("org", "org").add(Restrictions.eq("org.code", orgCode))
				.add(Restrictions.eq("delfg", "0"))
				.add(Restrictions.eq("enable", "1"));
		List<OrgMember> omList = find(dc);
		for (OrgMember om : omList)
			res.add(om.getMember());
		return res;
	}

	/**
	 * 找到本人的组织领导 type=2,得到部门领导 type=3,得到部门分管领导
	 * 
	 * @param code
	 *            工号
	 * @return
	 */
	public String getDirectLeader(String Code, String type) {
		String res = "";
		Member member = findMemberByCode(Code);
		Org org = findMyOffiOrg(member);
		List<Member> mList = null;

		mList = findMemInOrg(getLeaderOrg(org, type).getCode());
		for (Member m : mList) {
			if (StringUtils.isEmpty(res))
				res = m.getCode();
			else {
				res = res + "," + m.getCode();
			}
		}
		return res;
	}

	private Org getLeaderOrg(Org org, String type) {
		Org res = null;
		if (StringUtils.equals(org.getOrglv(), "1")) { // 找到部门
			DetachedCriteria dc = DetachedCriteria.forClass(Org.class);
			dc.add(Restrictions.eq("parent", org))
					.add(Restrictions.eq("att1", type))
					.add(Restrictions.eq("delfg", "0"))
					.add(Restrictions.eq("enable", "1"));// 暂定att1为领导组标示2为部门领导，3为分管领导
			res = findBean(dc);
		} else {
			res = getLeaderOrg(org.getParent(), type);
		}
		return res;
	}

	/**
	 * 查找在职员工
	 * 
	 * @param code
	 * @return
	 */
	public Member findMemberByCode(String code) {
		DetachedCriteria dc = DetachedCriteria.forClass(Member.class);
		dc.add(Restrictions.eq("code", code))
				.add(Restrictions.eq("delfg", "0"));
		Member res = findBean(dc);
		return res;
	}

	/**
	 * 包含已离职人员
	 * 
	 * @param code
	 * @return
	 */
	public Member findAllMemberByCode(String code) {
		DetachedCriteria dc = DetachedCriteria.forClass(Member.class);
		dc.add(Restrictions.eq("code", code))
				.add(Restrictions.eq("delfg", "0"));
		Member res = findBean(dc);
		return res;
	}

	/**
	 * 找到组织
	 * 
	 * @param m
	 * @return
	 */
	public Org findOrgbyName(String name) {
		Org res = null;
		DetachedCriteria dc = DetachedCriteria.forClass(Org.class);
		dc.add(Restrictions.eq("descr", name)).add(
				Restrictions.eq("delfg", "0"));
		res = findBean(dc);
		return res;
	}

	/**
	 * 找到组织
	 * 
	 * @param m
	 * @return
	 */
	public Org findOrgbyCode(String code) {
		Org res = null;
		DetachedCriteria dc = DetachedCriteria.forClass(Org.class);
		dc.add(Restrictions.eq("code", code))
				.add(Restrictions.eq("delfg", "0"));
		res = findBean(dc);
		return res;
	}
	
	
	/**
	 * 根据材料员组织code，找到材料员
	 * @param depCode
	 * @return
	 */
	public String findClyByOrgCode(String depCode){
		String res="";
//		Org org = findOrgbyCode(depCode);
//		List<Member> mList = findClyByOrg(org);
		List<Member> mList = findMemInOrg(depCode);
		for (Member m : mList) {
			if (StringUtils.isEmpty(res))
				res = m.getCode();
			else {
				res = res + "," + m.getCode();
			}
		}
		return res;
	}
	
	/**
	 * 找到该员工上一级的材料人员,其中att1字段限制为6--材料人员组织
	 * @param o
	 * @return
	 */
	public String findParentOrgCly(String code) {
		String res = "";
		Member member = findMemberByCode(code);
		Org myOrg = findMyOffiOrg(member);
		int lev = Integer.parseInt(myOrg.getOrglv())-1;
		Org myParentOrg = findParentOrgByLeve(myOrg, lev);

		List<Member> mList = findClyByOrg(myParentOrg);
		
		for (Member m : mList) {
			if (StringUtils.isEmpty(res))
				res = m.getCode();
			else {
				res = res + "," + m.getCode();
			}
		}
		return res;
	}
	
	
	/**
	 * 找到该员工所在部门（中心）的材料人员
	 * @param code
	 * @return
	 */
	
	public String findDepOrgCly(String code){
		String res = "";
		Member member = findMemberByCode(code);
		Org myOrg = findMyOffiOrg(member);
		Org myDepOrg = findParentOrgByLeve(myOrg, 1);
		List<Member> mList = findClyByOrg(myDepOrg);
		for (Member m : mList) {
			if (StringUtils.isEmpty(res))
				res = m.getCode();
			else {
				res = res + "," + m.getCode();
			}
		}
		return res;
		
		
	}

	
	/**
	 * 根据组织Org,找到对应的材料人员Member
	 * @param myDepOrg
	 * @return
	 */
	public List<Member> findClyByOrg(Org myDepOrg) {
		Org clyOrg = findClyOrgByOrg(myDepOrg);
		List<Member> mList = null;
		if (clyOrg != null) {
			mList = findMemInOrg(clyOrg.getCode());
		}
		return mList;
	}

	
	/**
	 * 根据组织Org，找到（子）材料员组织
	 * @param myDepOrg
	 * @return
	 */
	public Org findClyOrgByOrg(Org myDepOrg) {
		DetachedCriteria dc = DetachedCriteria.forClass(Org.class);
		dc.add(Restrictions.eq("parent", myDepOrg))
		.add(Restrictions.eq("att1","6"))
		.add(Restrictions.eq("orge", "1200")) 
		.add(Restrictions.eq("delfg", "0"))
		.add(Restrictions.eq("enable", "1"));
		Org clyOrg = findBean(dc);
		return clyOrg;
	}
	
	

	public List<Org> getUnderOrg(Org org) {
		List<Org> res = new ArrayList<Org>();
		res.add(org);
		ppp(org, res);
		return res;
	}

	public void ppp(Org org, List<Org> res) {
		DetachedCriteria dc = DetachedCriteria.forClass(Org.class);
		dc.add(Restrictions.eq("parent", org))
				.add(Restrictions.eq("orge", "1000"))
				.add(Restrictions.eq("delfg", "0"));
		List<Org> orgs = find(dc);
		if (CollUtil.isNotEmpty(orgs)) {
			res.addAll(orgs);
			for (Org o : orgs) {
				ppp(o, res);
			}
		}
	}
}
